<template>
  <div class="echarts-box" ref="chartRef" :style="{ width: props.width, height: props.height }"></div>
</template>

<script lang="ts" setup>
import { onMounted, watch, ref, onBeforeUnmount, markRaw } from 'vue'
import echarts from '@/util/echarts'

interface Props {
  option: Object
  theme?: Object | string // 主题
  width?: string
  height?: string
  loading?: boolean
  onMouseclick?: (...args: any[]) => any
  onMouseover?: (...args: any[]) => any
  onMouseout?: (...args: any[]) => any
}

const props = withDefaults(defineProps<Props>(), {
  theme: null,
  width: '100%',
  height: '100%'
})

const chartRef = ref<HTMLDivElement>()
const chartInstance = ref<echarts.EChartsType>()

watch(props, () => {
  draw()
})
watch(
  () => props.loading,
  (loading: boolean) => {
    loading ? chartInstance.value.showLoading() : chartInstance.value.hideLoading()
  }
)

const init = () => {
  chartInstance.value = echarts.getInstanceByDom(chartRef.value)
  if (!chartInstance.value) {
    chartInstance.value = markRaw(echarts.init(chartRef.value, props.theme))
    draw()
  }
  // 绑定 click 事件：
  if (props.onMouseclick) {
    chartInstance.value.on('click', function (event: Object) {
      props.onMouseclick(event, chartInstance.value, props.option)
    })
  }
  // 绑定 mouseover 事件：
  if (props.onMouseover) {
    chartInstance.value.on('mouseover', function (event) {
      props.onMouseover(event, chartInstance.value, props.option)
    })
  }

  // 绑定 mouseout 事件：
  if (props.onMouseout) {
    chartInstance.value.on('mouseout', (event: Object) => {
      props.onMouseout(event, chartInstance.value, props.option)
    })
  }
}

const draw = () => {
  if (chartInstance.value) {
    setTimeout(() => {
      chartInstance.value.setOption(props.option, true)
    })
  }
}

const debounce = (fn: Function, delay?: number) => {
  let delays = delay || 500
  let timer: NodeJS.Timer | null
  return (...rest: Array<any>) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(function () {
      timer = null
      fn.apply(null, rest)
    }, delays)
  }
}

const resize = debounce(() => {
  chartInstance &&
    chartInstance.value.resize({
      animation: {
        duration: 300
      }
    })
}, 200)

let time = null
const pollingDraw = () => {
  time = setInterval(() => {
    chartInstance.value.clear()
    draw()
  }, 45000)
}

let autofitRef = false
onMounted(() => {
  init()
  resize()
  import.meta.env.PROD && pollingDraw()
  window.addEventListener('resize', resize)
})
onBeforeUnmount(() => {
  chartInstance.value?.dispose()
  window.removeEventListener('resize', resize)
  clearInterval(time)
})
defineExpose({ chartInstance, draw, resize })
//
</script>
<style></style>
